<?php
namespace App\Services\Auth;


use App\Models\User;
use DateTime;
use Firebase\JWT\JWT;
use Illuminate\Database\Capsule\Manager;
use Slim\Collection;

class Auth
{
     const SUBJECT_IDENTIFIER = 'username';

    /**
     * @var \Illuminate\Database\Capsule\Manager
     */
     private $db;

    /**
     * @var array
     */
     private $appConfig;

     public function __construct(Manager $db,Collection $appConfig)
     {
         $this->db = $db;
         $this->appConfig = $appConfig;
     }

    /**
     *  生成JWT token
     *
     * @param User $user
     * @return string
     */
    public function generateToken(User $user)
    {
        $now = new DateTime();
        if($user->token_expire<$now->getTimestamp()){
            $future = new DateTime("now +2 hours");
            $payload = [
                "iat" => $now->getTimeStamp(),
                "exp" => $future->getTimeStamp(),
                "jti" => base64_encode(random_bytes(16)),
                'iss' => $this->appConfig['app']['url'],  // Issuer
                "sub" => $user->{self::SUBJECT_IDENTIFIER},
            ];
            $secret = $this->appConfig['jwt']['secret'];
            $token  = JWT::encode($payload, $secret, $this->appConfig['jwt']['algorithm']);
            $user->token = $token;
            $user->token_expire = $future->getTimeStamp();
            $user->where('id',$user->id)->update(['token'=>$token,'token_expire'=>$future->getTimeStamp()]);
        }
        return $user;
    }

        /***
     *  校验用户名密码
     * @param $username
     * @param $password
     * @param int $type  1=password,2=code
     * @return bool|\App\Models\User
     */
     public function attempt($username,$password,$type=1){
         $user = User::where(['username'=>$username])->orwhere(['phone'=>$username])->first();
         if($user){
             if($type==1){
                 if($password == $user->code && $user->code_flag == 1){
                     return $user;
                 }

             }else{
                 if(md5(md5($password).$user->salt) == $user->password){
                     return $user;
                 }
             }
         }
         return false;
     }

    /**
     * Retrieve a user by the JWT token from the request
     *
     * @param \Slim\Http\Request $request
     *
     * @return User|null
     */
    public function requestUser(Request $request)
    {
        // Should add more validation to the present and validity of the token?
        if ($token = $request->getAttribute('token')) {
            return User::where(static::SUBJECT_IDENTIFIER, '=', $token->sub)->first();
        };
    }
}










































